package org.springblade.modules.mes.opcua.listener;

import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription;
import org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscriptionManager;
import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedDataItem;
import org.eclipse.milo.opcua.sdk.client.subscriptions.ManagedSubscription;
import org.eclipse.milo.opcua.stack.core.UaException;
import org.eclipse.milo.opcua.stack.core.types.builtin.DateTime;
import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;


/**
 * @author tarzan
 */
@Slf4j
public class OpcUaSubscriptionListener implements UaSubscriptionManager.SubscriptionListener {


	private Set<String> keys;
	private OpcUaClient client;

	public OpcUaSubscriptionListener(Set<String> keys, OpcUaClient client) {
		this.keys = keys;
		this.client=client;
	}

	@Override
	public void onKeepAlive(UaSubscription subscription, DateTime publishTime) {
//		log.info("onKeepAlive");
	}

	@Override
	public void onStatusChanged(UaSubscription subscription, StatusCode status) {
		log.info("onStatusChanged");
	}

	@Override
	public void onPublishFailure(UaException exception) {
		log.info("onPublishFailure");
	}

	@Override
	public void onNotificationDataLost(UaSubscription subscription) {
		log.info("onNotificationDataLost");
	}

	/**
	 * 重连时 尝试恢复之前的订阅失败时 会调用此方法
	 * @param uaSubscription 订阅
	 * @param statusCode 状态
	 */
	@Override
	public void onSubscriptionTransferFailed(UaSubscription uaSubscription, StatusCode statusCode) {
		log.info("恢复订阅失败 需要重新订阅");
		//在回调方法中重新订阅
		handlerNode(keys,client);
	}
	public void handlerNode(Set<String> keys, OpcUaClient client) {
		try {
			//创建订阅
			ManagedSubscription subscription = ManagedSubscription.create(client);
			List<NodeId> nodeIdList = new ArrayList<>();
			for (String key : keys) {
				log.info(key);
				nodeIdList.add(new NodeId(2, key));
			}
			//监听
			List<ManagedDataItem> dataItemList = subscription.createDataItems(nodeIdList);
			OpcUaListener prdDataValueListener = SpringUtil.getBean(OpcUaListener.class);
			for (ManagedDataItem managedDataItem : dataItemList) {
				managedDataItem.addDataValueListener(prdDataValueListener);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
